package cn.net.dpi.wlqc.server.client;

import cn.net.dpi.wlqc.server.proto.ThirdTrackBatch;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;

import java.net.URI;

@Slf4j
public class NettyProtobufHttpClient {

    public static void main(String[] args) throws Exception {
        // 👇 1. 目标 URL
        URI uri = new URI("http://localhost:8090/ecar/track/upload");
        String host = uri.getHost();
        int port = uri.getPort();

        // 👇 2. 构造 Protobuf 请求体
        ThirdTrackBatch.ThirdPoints point = ThirdTrackBatch.ThirdPoints.newBuilder()
                .setGpsTime(System.currentTimeMillis())
                .setLatitude(31.23)
                .setLongitude(121.47)
                .setAltitude(20)
                .setAccuracy(5)
                .setGpsBearing(180)
                .setSpeed(60)
                .setSystemTime(System.currentTimeMillis())
                .setLocationType(ThirdTrackBatch.ThirdPoints.LocationType.GPS)
                .setCoordinateType(ThirdTrackBatch.ThirdPoints.CoordinateType.GCJ02)
                .build();

        ThirdTrackBatch.ThirdTrackInfo trackInfo = ThirdTrackBatch.ThirdTrackInfo.newBuilder()
                .setDeviceId("device001")
                .addPoints(point)
                .build();

        ThirdTrackBatch.ThirdTrackReq req = ThirdTrackBatch.ThirdTrackReq.newBuilder()
                .setTrackId("track-001")
                .addTracks(trackInfo)
                .build();

        byte[] protobufBytes = req.toByteArray();

        // 👇 3. 启动 Netty 客户端
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<Channel>() {
                        @Override
                        protected void initChannel(Channel ch) {
                            ChannelPipeline p = ch.pipeline();
                            p.addLast(new HttpClientCodec());
                            p.addLast(new HttpObjectAggregator(1024 * 1024));
                            p.addLast(new SimpleChannelInboundHandler<FullHttpResponse>() {
                                @Override
                                public void channelActive(ChannelHandlerContext ctx) {
                                    // 👇 4. 构造 HTTP 请求（POST）
                                    FullHttpRequest request = new DefaultFullHttpRequest(
                                            HttpVersion.HTTP_1_1,
                                            HttpMethod.POST,
                                            uri.getRawPath(),
                                            Unpooled.wrappedBuffer(protobufBytes)
                                    );

                                    request.headers().set(HttpHeaderNames.HOST, host);
                                    request.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/x-protobuf");
                                    request.headers().set(HttpHeaderNames.CONTENT_LENGTH, protobufBytes.length);

                                    ctx.writeAndFlush(request);
                                }

                                @Override
                                protected void channelRead0(ChannelHandlerContext ctx, FullHttpResponse response) {
                                    log.info("响应状态: {}", response.status());
                                    log.info("响应内容: {}", response.content().toString(CharsetUtil.UTF_8));
                                    ctx.close();
                                }
                            });
                        }
                    });

            ChannelFuture f = b.connect(host, port).sync();
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }
}
